/*
 * SemolThread.h
 *
 *  Created on: 2013-02-01
 *      Author: mathieu
 */

#ifndef SEMOLTHREAD_H_
#define SEMOLTHREAD_H_

#include "semol/core/SemolExp.h" // DLL export/import defines

#include <utilite/UThread.h>
#include <utilite/UEventsHandler.h>

#include "semol/core/Parameters.h"
#include "semol/core/SemolEvent.h"

#include <stack>

namespace semol {

class Semol;

class SEMOL_EXP SemolThread :
	public UThread,
	public UEventsHandler
{
public:
	enum State {
		kStateIdle,
		kStateDetecting,
		kStateReseting,
		kStateChangingParameters,
		kStateDumpingMemory,
		kStateDumpingPrediction,
		kStateGeneratingGraph,
		kStateGeneratingLocalGraph,
		kStateDeletingMemory,
		kStateCleanSensorsBuffer
	};

public:
	SemolThread();
	virtual ~SemolThread();

	void clearBufferedSensors();

protected:
	virtual void handleEvent(UEvent * anEvent);

private:
	virtual void mainLoop();
	virtual void mainLoopKill();

	void process();
	void addSensorimotor(const std::list<SensorRaw> & sensors, const std::list<Actuator> & actuators);
	void getSensorimotor(std::list<SensorRaw> & sensors, std::list<Actuator> & actuators);
	void pushNewState(State newState, const ParametersMap & parameters = ParametersMap());

private:
	Semol * semol_;

	UMutex stateMutex_;
	std::stack<State> state_;
	std::stack<ParametersMap> stateParam_;

	int sensorsBufferMaxSize_;
	std::list<std::pair<std::list<SensorRaw>, std::list<Actuator> > > sensorimotorBuffer_;
	UMutex sensorimotorMutex_;
	USemaphore sensorimotorAdded_;
};

} //end namespace semol

#endif /* SEMOLTHREAD_H_ */
